#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/backlight.h>
#include <linux/platform_device.h>
#include <linux/fb.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
#include <linux/power_supply.h>
//#include <linux/video_output.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
#include <linux/jiffies.h>
#include <linux/miscdevice.h>
//#include <asm/bootinfo.h>
#include <linux/module.h>
#include <linux/device.h>
//#include <ec_it8528.h>

#include "../ec_dev_inc/ec_dev_drv.h"

#define BIT1 0x02

#define LPC_EC_INDEX_PORT 0x2E
#define LPC_EC_DATA_PORT 0x2F

#define SIO_CONFIG_CTRL       0x02
#define SIO_CONFIG_PORT       0x2E

static int EnterConfigMode(void);
static int ExitConfigMode(void);

//static ssize_t ec_it8733_dev_config(unsigned char *ecram_vals);
static struct class  *ec_it8733_dev_class;
static struct device *ec_it8733_dev_class_dev;


static int ec_it8733_dev_open(struct inode *inode, struct file *file)
{
	return 0;
}

int EnterConfigMode(void)
{
  UINT8  PnpKey;

#if 0
  	int data=ec_inb(0x62);
	dbg_prt_rn("0x62=%02X ", data);

  	data=ec_inb(0x66);
	dbg_prt_rn("0x66=%02X ", data);
  #endif
#if 1
  PnpKey = 0x87;
  outb ( PnpKey, SIO_CONFIG_PORT);
  PnpKey = 0x01;
  outb ( PnpKey, SIO_CONFIG_PORT);
  PnpKey = 0x55;
  outb ( PnpKey, SIO_CONFIG_PORT);
  PnpKey = 0x55;
  outb ( PnpKey, SIO_CONFIG_PORT);
#endif  
  return 0;
}

int ExitConfigMode(void)
{
  UINT8  RegData = 0x00;
#if 1
  outb ( SIO_CONFIG_CTRL,LPC_EC_INDEX_PORT);
  RegData = inb ( LPC_EC_DATA_PORT) | BIT1;
  outb ( SIO_CONFIG_CTRL,LPC_EC_INDEX_PORT);  
  outb ( RegData,LPC_EC_DATA_PORT);
#endif
  return 0;
}

ssize_t get_it8733_chip_id( unsigned char *Chipid0, unsigned char *Chipid1)
{
  //int i;
	//unsigned char Chipid0,Chipid1 =0;
	UINT16  DataTemp;
  EnterConfigMode();
  EnterConfigMode();
  outb ( 0x20,LPC_EC_INDEX_PORT);  
  *Chipid0 = inb (LPC_EC_DATA_PORT);
  //dbg_prt("Chipid0 = %02x \n",Chipid0);

  //ecram_vals[0]=Chipid0;

  outb ( 0x21,LPC_EC_INDEX_PORT);
  *Chipid1 = inb (LPC_EC_DATA_PORT); 
  //dbg_prt("Chipid1 = %02x \n",Chipid1);

  outb ( 0x22,LPC_EC_INDEX_PORT);

  DataTemp = inb (LPC_EC_DATA_PORT);
  //dbg_prt("DataTemp = %02x \n",DataTemp);
  ExitConfigMode ();
  return 0;
}


char strbuf[100]={0};
static long ec_it8733_dev_ioctl(struct file *file,
    unsigned int cmd, unsigned long arg)
{
  int err = 0;
  void __user *uarg = (void __user *) arg;

  //printk("fdfsd\n");

  switch (cmd) 
  {
    case EC_DEV_BYTE_IN:
    {
      typEcDev ecdev;
      	//printk(              "     CPU   temprature = %08d; \n",93 );

      if (copy_from_user(&ecdev, uarg, sizeof(ecdev)))
        return -EFAULT; 
      ecdev.value=inb(ecdev.port);
      printk(" in ecdev.value=%02X; ecdev.port =%04X\n", ecdev.value ,ecdev.port);
      if (copy_to_user(uarg, &ecdev, sizeof(ecdev)))
        return -EFAULT; 
      return 0;    
    }

    case EC_DEV_BYTE_OUT:
    {
      typEcDev ecdev;
      if (copy_from_user(&ecdev, uarg, sizeof(ecdev)))
        return -EFAULT; 


      outb(ecdev.value,ecdev.port);
      printk(" out ecdev.value=%02X; ecdev.port =%04X\n", ecdev.value ,ecdev.port);
      return 0;   
    }

    
    case EC_DEV_GET_CHIP_ID:
    {
      typEcDev ecdev;
      unsigned char Chipid0;
      unsigned char Chipid1;
      	//printk(              "     CPU   temprature = %08d; \n",93 );

      if (copy_from_user(&ecdev, uarg, sizeof(ecdev)))
        return -EFAULT; 
      
      get_it8733_chip_id( &Chipid0, &Chipid1);
      ecdev.value=Chipid0;
      ecdev.port=Chipid1;
      printk(" in ecdev.value=%02X; ecdev.port =%04X\n", ecdev.value ,ecdev.port);
      if (copy_to_user(uarg, &ecdev, sizeof(ecdev)))
        return -EFAULT; 
      return 0;    
    }    


  }
  return err;
}



ssize_t ec_it8733_dev_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
	unsigned char ecram_vals[256];
	//unsigned int i;
#if 0
	for(i = 0; i < 256;i++)
	{
		ecram_vals[i] = it8528_read(i);
	}
#endif
	memset(ecram_vals, 0xFF, sizeof(ecram_vals));
	//ec_it8733_dev_config(&ecram_vals[0]);

  if(copy_to_user(buf, ecram_vals, sizeof(ecram_vals)))
    return -EFAULT; 

	return sizeof(ecram_vals);
}

static ssize_t ec_it8733_dev_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
	int val;	

	if(copy_from_user(&val, buf, count))
    return -EFAULT; 


	//it8528_write((val>>8)&0xff , val&0xff);
	
	return 0;
}


static struct file_operations ec_it8733_dev_fops = {
    .owner  =   THIS_MODULE,    /* ����һ���꣬�������ģ��ʱ�Զ�������__this_module���� */
    .open   =   ec_it8733_dev_open,     
	.read	=	ec_it8733_dev_read,	  
	.write	=	ec_it8733_dev_write,
  //.ioctl  = ec_it8733_dev_ioctl,	
  .unlocked_ioctl  =ec_it8733_dev_ioctl,
};


int major;
static int ec_it8733_dev_init(void)
{
	major = register_chrdev(0, "ec_it8733_dev", &ec_it8733_dev_fops); // ע��, �����ں�

	ec_it8733_dev_class = class_create(THIS_MODULE, "ecit8733dev");

	ec_it8733_dev_class_dev = device_create(ec_it8733_dev_class, NULL, MKDEV(major, 0), NULL, "ec_it8733"); /* /dev/ecit8733*/


	return 0;
}

static void ec_it8733_dev_exit(void)
{
	unregister_chrdev(major, "ec_it8733_dev");
	device_unregister(ec_it8733_dev_class_dev);
	class_destroy(ec_it8733_dev_class);
}


module_init(ec_it8733_dev_init);

module_exit(ec_it8733_dev_exit);

MODULE_LICENSE("GPL");

